#pragma once

#include "AcquisitionMode.h"
#include "BufferTriggerMode.h"
#include "SpectrumDataClr.h"
#include "StrobeMode.h"
#include "NetSpectrometerErrorCode.h"
#include <cstdint>

namespace Ideaoptics
{
	/// <summary>
	/// 光谱仪对象类
	/// </summary>
	class IMultiChannelSpectrometer
	{
		/// <summary>
		/// 连接光谱仪
		/// </summary>
		/// <returns></returns>
		virtual bool Connect() = 0;
		/// <summary>
		/// 断开连接
		/// </summary>
		virtual void Disconnect() = 0;

		/// <summary>
		/// 注册光谱推送回调(拼谱后,只有启用拼谱功能才生效)
		/// </summary>
		/// <param name="callback">回调函数,参数分别为光谱仪对象,光谱数据(数据长度一定为像素数),用户数据</param>
		/// <param name="userData">用户数据</param>
		virtual void RegisterPushedSpectrumReceivedCallback(void (*callback)(IMultiChannelSpectrometer*, SpectrumDataClr*, void*), void* userData) = 0;
		/// <summary>
		/// 注册各通道光谱推送回调
		/// </summary>
		/// <param name="callback">回调函数,参数分别为光谱仪对象,光谱数据列表(长度为通道数,每个通道的数据长度一定为像素数),通道数,用户数据</param>
		/// <param name="userData"></param>
		virtual void RegisterPushedSpectrumOfEachChannelReceivedCallback(void (*callback)(IMultiChannelSpectrometer*, SpectrumDataClr*, int, void*), void* userData) = 0;
		/// <summary>
		/// 注册单个通道光谱推送回调
		/// </summary>
		/// <param name="callback">回调函数,参数分别为光谱仪对象,光谱数据(数据长度一定为像素数),用户数据</param>
		/// <param name="userData">用户数据</param>
		virtual void RegisterPushedSpectrumOfOneChannelReceivedCallback(void (*callback)(IMultiChannelSpectrometer*, char*, SpectrumDataClr*, void*), void* userData) = 0;
		/// <summary>
		/// 注册通道连接丢失回调
		/// </summary>
		/// <param name="callback">回调函数,参数分别为光谱仪对象,掉线通道的序列号,用户数据</param>
		/// <param name="userData"></param>
		virtual void RegisterConnectionLostCallback(void (*callback)(IMultiChannelSpectrometer*, char*, void*), void* userData) = 0;
		/// <summary>
		/// 注销光谱推送回调
		/// </summary>
		virtual void UnregisterPushedSpectrumReceivedCallback() = 0;
		/// <summary>
		/// 注销单通道光谱推送回调
		/// </summary>
		virtual void UnregisterPushedSpectrumOfOneChannelReceivedCallback() = 0;
		/// <summary>
		/// 注销各通道光谱推送回调
		/// </summary>
		virtual void UnregisterPushedSpectrumOfEachChannelReceivedCallback() = 0;
		/// <summary>
		/// 注销通道连接丢失回调
		/// </summary>
		virtual void UnregisterConnectionLostCallback() = 0;

		/// <summary>
		/// 读取各通道的序列号
		/// </summary>
		/// <param name="sn"></param>
		/// <param name="numOfChannels"></param>
		/// <param name="sizeOfEachSN"></param>
		virtual int GetSerialNumber(char** sn, size_t numOfChannels, size_t sizeOfEachSN) = 0;
		/// <summary>
		/// 读取型号
		/// </summary>
		/// <param name="name"></param>
		/// <param name="size"></param>
		virtual void GetTypeName(char* name, size_t size) = 0;
		/// <summary>
		/// 读取拼谱后的像素数
		/// </summary>
		/// <returns></returns>
		virtual int GetPixelNumber() = 0;
		/// <summary>
		/// 获取单个通道的像素数
		/// </summary>
		/// <returns></returns>
		virtual int GetPixelNumberOfOneChannel() = 0;
		/// <summary>
		/// 读取最小积分时间(ms)
		/// </summary>
		/// <returns></returns>
		virtual double GetMinIntegrationTime() = 0;
		/// <summary>
		/// 读取最大积分时间(ms)
		/// </summary>
		/// <returns></returns>
		virtual double GetMaxIntegrationTime() = 0;
		/// <summary>
		/// 读取各通道的波长序列
		/// </summary>
		/// <param name="wavelength"></param>
		/// <param name="numOfChannels"></param>
		/// <param name="size"></param>
		/// <returns></returns>
		virtual int GetWavelengthOfEachChannel(double** wavelength, size_t numOfChannels, size_t size) = 0;
		/// <summary>
		/// 读取拼谱后的波长序列(只有启用拼谱时有效)
		/// </summary>
		/// <param name="wavelength"></param>
		/// <param name="size"></param>
		/// <returns></returns>
		virtual int GetWavelength(double* wavelength, size_t size) = 0;
		/// <summary>
		/// 读取单个通道的波长序列
		/// </summary>
		/// <param name="index"></param>
		/// <param name="wavelength"></param>
		/// <param name="size"></param>
		virtual int GetWavelength(int index, double* wavelength, size_t size) = 0;
		/// <summary>
		/// 读取单个通道的波长序列
		/// </summary>
		/// <param name="sn"></param>
		/// <param name="wavelength"></param>
		/// <param name="size"></param>
		virtual int GetWavelength(const char* sn, double* wavelength, size_t size) = 0;
		/// <summary>
		/// 设置所有通道的积分时间(ms)
		/// </summary>
		/// <param name="intTime"></param>
		/// <returns></returns>
		virtual bool SetIntegrationTime(double intTime) = 0;
		/// <summary>
		/// 设置单个通道的积分时间(ms)
		/// </summary>
		/// <param name="index"></param>
		/// <param name="intTime"></param>
		/// <returns></returns>
		virtual bool SetIntegrationTime(int index, double intTime) = 0;
		/// <summary>
		/// 设置单个通道的积分时间(ms)
		/// </summary>
		/// <param name="sn"></param>
		/// <param name="intTime"></param>
		/// <returns></returns>
		virtual bool SetIntegrationTime(const char* sn, double intTime) = 0;
		/// <summary>
		/// 读取全部通道的积分时间(ms)
		/// </summary>
		/// <param name="intTime"></param>
		/// <param name="size"></param>
		/// <returns></returns>
		virtual bool GetIntegrationTime(double* intTimes, size_t size) = 0;
		/// <summary>
		/// 读取单个通道的积分时间(ms)
		/// </summary>
		/// <param name="index"></param>
		/// <param name="intTime"></param>
		/// <returns></returns>
		virtual bool GetIntegrationTime(int index, double& intTime) = 0;
		/// <summary>
		/// 读取单个通道的积分时间(ms)
		/// </summary>
		/// <param name="sn"></param>
		/// <param name="intTime"></param>
		/// <returns></returns>
		virtual bool GetIntegrationTime(const char* sn, double& intTime) = 0;
		/// <summary>
		/// 设置触发模式
		/// </summary>
		/// <param name="mode"></param>
		/// <param name="n"></param>
		/// <returns></returns>
		virtual bool SetTriggerMode(AcquisitionMode mode, uint16_t n) = 0;
		/// <summary>
		/// 设置单个通道的触发模式
		/// </summary>
		/// <param name="index"></param>
		/// <param name="mode"></param>
		/// <param name="n"></param>
		/// <returns></returns>
		virtual bool SetTriggerMode(int index, AcquisitionMode mode, uint16_t n) = 0;
		/// <summary>
		/// 设置单个通道的触发模式
		/// </summary>
		/// <param name="sn"></param>
		/// <param name="mode"></param>
		/// <param name="n"></param>
		/// <returns></returns>
		virtual bool SetTriggerMode(const char* sn, AcquisitionMode mode, uint16_t n) = 0;
		/// <summary>
		/// 读取触发模式
		/// </summary>
		/// <param name="mode"></param>
		/// <param name="n"></param>
		/// <returns></returns>
		virtual bool GetTriggerMode(AcquisitionMode* mode, uint16_t* n) = 0;
		/// <summary>
		/// 读取单个通道的触发模式
		/// </summary>
		/// <param name="index"></param>
		/// <param name="mode"></param>
		/// <param name="n"></param>
		/// <returns></returns>
		virtual bool GetTriggerMode(int index, AcquisitionMode* mode, uint16_t* n) = 0;
		/// <summary>
		/// 读取单个通道的触发模式
		/// </summary>
		/// <param name="sn"></param>
		/// <param name="mode"></param>
		/// <param name="n"></param>
		/// <returns></returns>
		virtual bool GetTriggerMode(const char* sn, AcquisitionMode* mode, uint16_t* n) = 0;
		/// <summary>
		/// 设置触发开关
		/// </summary>
		/// <param name="sw"></param>
		/// <returns></returns>
		virtual bool SetTriggerSwitch(bool sw) = 0;
		/// <summary>
		/// 读取触发开关
		/// </summary>
		/// <param name="sw"></param>
		/// <returns></returns>
		virtual bool GetTriggerSwitch(bool& sw) = 0;
		/// <summary>
		/// 设置所有通道的触发延迟(ms)
		/// </summary>
		/// <param name="delay"></param>
		/// <returns></returns>
		virtual bool SetTriggerDelay(double delay) = 0;
		/// <summary>
		/// 设置单个通道的触发延迟(ms)
		/// </summary>
		/// <param name="index"></param>
		/// <param name="delay"></param>
		/// <returns></returns>
		virtual bool SetTriggerDelay(int index, double delay) = 0;
		/// <summary>
		/// 设置单个通道的触发延迟(ms)
		/// </summary>
		/// <param name="index"></param>
		/// <param name="delay"></param>
		/// <returns></returns>
		virtual bool SetTriggerDelay(const char* sn, double delay) = 0;
		/// <summary>
		/// 获取所有通道的触发延迟(ms)
		/// </summary>
		/// <param name="delays"></param>
		/// <param name="size"></param>
		/// <returns></returns>
		virtual bool GetTriggerDelay(double* delays, size_t size) = 0;
		/// <summary>
		/// 获取单个通道的触发延迟(ms)
		/// </summary>
		/// <param name="index"></param>
		/// <param name="delays"></param>
		/// <returns></returns>
		virtual bool GetTriggerDelay(int index, double& delay) = 0;
		/// <summary>
		/// 获取单个通道的触发延迟(ms)
		/// </summary>
		/// <param name="sn"></param>
		/// <param name="delays"></param>
		/// <returns></returns>
		virtual bool GetTriggerDelay(const char* sn, double& delay) = 0;
		/// <summary>
		/// 触发复位(放弃当前正在执行的积分操作)
		/// </summary>
		/// <returns></returns>
		virtual bool TriggerReset() = 0;
		/// <summary>
		/// 触发复位(放弃当前正在执行的积分操作)
		/// <param name="index"></param>
		/// </summary>
		/// <returns></returns>
		virtual bool TriggerReset(int index) = 0;
		/// <summary>
		/// 触发复位(放弃当前正在执行的积分操作)
		/// <param name="sn"></param>
		/// </summary>
		/// <returns></returns>
		virtual bool TriggerReset(const char* sn) = 0;
		/// <summary>
		/// 软件触发
		/// </summary>
		/// <returns></returns>
		virtual bool SoftTrigger() = 0;
		/// <summary>
		/// 软件触发
		/// </summary>
		/// <param name="index"></param>
		/// <returns></returns>
		virtual bool SoftTrigger(int index) = 0;
		/// <summary>
		/// 软件触发
		/// </summary>
		/// <param name="sn"></param>
		/// <returns></returns>
		virtual bool SoftTrigger(const char* sn) = 0;

		/// <summary>
		/// 读取拼谱后光谱(只有启用拼谱时有效)
		/// </summary>
		/// <param name="spectrum"></param>
		/// <returns></returns>
		virtual bool GetSpectrum(SpectrumDataClr* spectrum) = 0;
		/// <summary>
		/// 读取各通道的光谱
		/// </summary>
		/// <param name="spectrum"></param>
		/// <param name="numOfChannels"></param>
		/// <returns></returns>
		virtual bool GetSpectrumOfEachChannel(SpectrumDataClr* spectrum, int numOfChannels) = 0;

		/// <summary>
		/// 开启主动推送
		/// </summary>
		/// <param name="enableStitching"></param>
		/// <returns></returns>
		virtual bool EnableSpectrumPushing(bool enableStitching) = 0;
		/// <summary>
		/// 开启单个通道的主动推送
		/// </summary>
		/// <param name="enableStitching"></param>
		/// <returns></returns>
		virtual bool EnableSpectrumPushing(int index) = 0;
		/// <summary>
		/// 开启单个通道的主动推送
		/// </summary>
		/// <param name="enableStitching"></param>
		/// <returns></returns>
		virtual bool EnableSpectrumPushing(const char* sn) = 0;
		/// <summary>
		/// 关闭主动推送
		/// </summary>
		/// <returns></returns>
		virtual bool DisableSpectrumPushing() = 0;
		/// <summary>
		/// 关闭单个通道的主动推送
		/// </summary>
		/// <returns></returns>
		virtual bool DisableSpectrumPushing(int index) = 0;
		/// <summary>
		/// 关闭单个通道的主动推送
		/// </summary>
		/// <returns></returns>
		virtual bool DisableSpectrumPushing(const char* sn) = 0;

		/// <summary>
		/// 设置频闪模式
		/// </summary>
		/// <param name="mode"></param>
		/// <returns></returns>
		virtual bool SetStrobeOutMode(StrobeMode mode) = 0;
		/// <summary>
		/// 读取频闪模式
		/// </summary>
		/// <param name="mode"></param>
		/// <returns></returns>
		virtual bool GetStrobeOutMode(StrobeMode& mode) = 0;
		/// <summary>
		/// 设置频闪开关
		/// </summary>
		/// <param name="onoff"></param>
		/// <returns></returns>
		virtual bool SetStrobeSwitch(bool onoff) = 0;
		/// <summary>
		/// 读取频闪开关
		/// </summary>
		/// <param name="onoff"></param>
		/// <returns></returns>
		virtual bool GetStrobeSwitch(bool& onoff) = 0;
		/// <summary>
		/// 设置频闪延迟(ms)
		/// </summary>
		/// <param name="delayInMs"></param>
		/// <returns></returns>
		virtual bool SetStrobeDelay(double delayInMs) = 0;
		/// <summary>
		/// 读取频闪延迟(ms)
		/// </summary>
		/// <param name="delayInMs"></param>
		/// <returns></returns>
		virtual bool GetStrobeDelay(double& delayInMs) = 0;
		/// <summary>
		/// 设置频闪脉宽(ms)
		/// </summary>
		/// <param name="widthInMs"></param>
		/// <returns></returns>
		virtual bool SetStrobeWidth(double widthInMs) = 0;
		/// <summary>
		/// 读取频闪脉宽(ms)
		/// </summary>
		/// <param name="widthInMs"></param>
		/// <returns></returns>
		virtual bool GetStrobeWidth(double& widthInMs) = 0;
		/// <summary>
		/// 设置频闪间隔(ms)
		/// </summary>
		/// <param name="intervalInMs"></param>
		/// <returns></returns>
		virtual bool SetStrobeInterval(double intervalInMs) = 0;
		/// <summary>
		/// 读取频闪间隔(ms)
		/// </summary>
		/// <param name="intervalInMs"></param>
		/// <returns></returns>
		virtual bool GetStrobeInterval(double& intervalInMs) = 0;

		/// <summary>
		/// 设置缓存谱模式
		/// </summary>
		/// <param name="enable"></param>
		/// <param name="mode"></param>
		/// <param name="totalFrames"></param>
		/// <returns></returns>
		virtual bool SetBufferMode(bool enable, BufferTriggerMode mode, uint32_t totalFrames) = 0;
		/// <summary>
		/// 读取缓存谱模式
		/// </summary>
		/// <param name="enable"></param>
		/// <param name="mode"></param>
		/// <param name="totalFrames"></param>
		/// <returns></returns>
		virtual bool GetBufferMode(bool* enable, BufferTriggerMode* mode, uint32_t* totalFrames, uint32_t* currentFrames) = 0;
		/// <summary>
		/// 读取缓存谱，每次最多读取1000张光谱，若尝试读取超过1000张会返回false
		/// </summary>
		/// <param name="startAddress"></param>
		/// <param name="endAddress"></param>
		/// <param name="spectrumData"></param>
		/// <param name="retryNum"></param>
		/// <returns></returns>
		virtual bool GetBufferedSpectra(int startAddress, int endAddress, SpectrumDataClr* spectrumData, size_t* dataSize, int retryNum = 1) = 0;
		/// <summary>
		/// 读取各通道的缓存谱，每次最多读取1000张光谱，若尝试读取超过1000张会返回false
		/// </summary>
		/// <param name="startAddress"></param>
		/// <param name="endAddress"></param>
		/// <param name="spectrumData"></param>
		/// <param name="numOfChannels"></param>
		/// <param name="retryNum"></param>
		/// <returns></returns>
		virtual bool GetBufferedSpectraOfEachChannel(int startAddress, int endAddress, SpectrumDataClr** spectrumData, int numOfChannels, int retryNum = 1) = 0;
		/// <summary>
		/// 强制中断缓存谱读取。调用该接口后GetBufferedSpectra()会立刻返回false
		/// </summary>
		/// <returns></returns>
		virtual void ForceStopGetBufferedSpectra() = 0;
		/// <summary>
		/// 清除缓存谱
		/// </summary>
		/// <returns></returns>
		virtual bool ClearBuffer() = 0;
		/// <summary>
		/// 设置可调增益(范围为1-6倍)
		/// </summary>
		/// <returns></returns>
		virtual bool SetSignalGain(bool toFlash, double gain) = 0;
		/// <summary>
		/// 设置单个通道的可调增益(范围为1-6倍)
		/// </summary>
		/// <returns></returns>
		virtual bool SetSignalGain(int index, bool toFlash, double gain) = 0;
		/// <summary>
		/// 设置单个通道的可调增益(范围为1-6倍)
		/// </summary>
		/// <returns></returns>
		virtual bool SetSignalGain(const char* sn, bool toFlash, double gain) = 0;
		/// <summary>
		/// 读取可调增益
		/// </summary>
		/// <returns></returns>
		virtual bool GetSignalGain(bool fromFlash, double* gains, size_t size) = 0;
		/// <summary>
		/// 读取单个通道的可调增益
		/// </summary>
		/// <returns></returns>
		virtual bool GetSignalGain(int index, bool fromFlash, double& gain) = 0;
		/// <summary>
		/// 读取单个通道的可调增益
		/// </summary>
		/// <returns></returns>
		virtual bool GetSignalGain(const char* sn, bool fromFlash, double& gain) = 0;
		/// <summary>
		/// 读取各通道PCB温度
		/// </summary>
		/// <param name="temperatures"></param>
		/// <returns></returns>
		virtual bool GetPcbTemperature(double* temps, size_t size) = 0;
		/// <summary>
		/// 设置所有通道的平均次数
		/// </summary>
		/// <param name="count"></param>
		/// <returns></returns>
		virtual bool SetAverage(int count) = 0;
		/// <summary>
		/// 设置单个通道的平均次数
		/// </summary>
		/// <param name="index"></param>
		/// <param name="count"></param>
		/// <returns></returns>
		virtual bool SetAverage(int index, int count) = 0;
		/// <summary>
		/// 设置单个通道的平均次数
		/// </summary>
		/// <param name="sn"></param>
		/// <param name="count"></param>
		/// <returns></returns>
		virtual bool SetAverage(const char* sn, int count) = 0;
		/// <summary>
		/// 获取所有通道的平均次数
		/// </summary>
		/// <param name="counts"></param>
		/// <param name="size"></param>
		/// <returns></returns>
		virtual bool GetAverage(int* counts, size_t size) = 0;
		/// <summary>
		/// 获取单个通道的平均次数
		/// </summary>
		/// <param name="index"></param>
		/// <param name="count"></param>
		/// <returns></returns>
		virtual bool GetAverage(int index, int& count) = 0;
		/// <summary>
		/// 获取单个通道的平均次数
		/// </summary>
		/// <param name="sn"></param>
		/// <param name="count"></param>
		/// <returns></returns>
		virtual bool GetAverage(const char* sn, int& count) = 0;

		/// <summary>
		/// 获取上一个错误信息
		/// </summary>
		/// <param name="msg"></param>
		/// <param name="size"></param>
		/// <returns></returns>
		virtual NetSpectrometerErrorCode GetLastError(char* msg, size_t size) = 0;
	};
}